﻿// CTlmWebserviceThread.cpp: 实现文件
//

#include "pch.h"
#include "RTOC-Data-Interface.h"
#include "CTlmWebserviceThread.h"


/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CTlmWebserviceThread

IMPLEMENT_DYNCREATE(CTlmWebserviceThread, CWinThread)

CTlmWebserviceThread::CTlmWebserviceThread()
{
	m_nYQHErrorTick = 0;
	m_nZXQErrorTick = 0;
}

CTlmWebserviceThread::~CTlmWebserviceThread()
{
}

#define DEGUBINDEX 0
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//数据湖接口实现
CString CTlmWebserviceThread::PostWellRT(CString strToken, CString strClientID, CString strHeadBody, CString strWN)
{
	CString strTemp, strReturn = _T("");
	CString URLPost;
	URLPost.Format(_T("%s?token=%s&clientId=%s&mdType=CD_WELLBORE"), gl.tlm.strURL2, strToken, strClientID);
	struct soap* soap = NULL;
	char* urlpost = NULL, * context = NULL;

	try
	{
		char* buf = NULL;
		size_t len;

		// 将CString转换为char* 
		urlpost = wchar2char(URLPost);
		context = wchar2char(strHeadBody);

		// 创建SOAP对象
		soap = soap_new();
		soap_set_omode(soap, SOAP_IO_CHUNK);
		soap_register_plugin(soap, http_post);

		// 发送SOAP请求
		if (soap_post_connect(soap, urlpost, NULL, "application/json") || soap_send(soap, context) || soap_end_send(soap))
		{
			strTemp.Format(_T("Error：PostWellRT->soap_http_get_connect %d---%s"), m_nWellIndex, sw.strWN);
			if (m_nWellIndex == DEGUBINDEX)
				WriteLog(strTemp);
			::EnterCriticalSection(&m_cOther);
			gl.m_strErrorMsg = _T("Error：PostWellRT->soap_http_get_connect: ") + strWN;
			::LeaveCriticalSection(&m_cOther);
			throw std::runtime_error("SOAP post connect failed");
		}

		if (soap_begin_recv(soap))
		{
			strTemp.Format(_T("Error：PostWellRT->soap_begin_recv %d---%s"), m_nWellIndex, sw.strWN);
			if (m_nWellIndex == DEGUBINDEX)
				WriteLog(strTemp);
			::EnterCriticalSection(&m_cOther);
			gl.m_strErrorMsg = _T("Error：PostWellRT->soap_begin_recv: ") + strWN;
			::LeaveCriticalSection(&m_cOther);
			throw std::runtime_error("SOAP begin receive failed");
		}

		if (soap_http_body(soap, &buf, &len))
		{
			strTemp.Format(_T("Error：PostWellRT->soap_http_body %d---%s"), m_nWellIndex, sw.strWN);
			if (m_nWellIndex == DEGUBINDEX)
				WriteLog(strTemp);
			::EnterCriticalSection(&m_cOther);
			gl.m_strErrorMsg = _T("Error：PostWellRT->soap_http_body: ") + strWN;
			::LeaveCriticalSection(&m_cOther);
			throw std::runtime_error("SOAP body read failed");
		}

		if (soap_end_recv(soap))
		{
			strTemp.Format(_T("Error：PostWellRT->soap_end_recv %d---%s"), m_nWellIndex, sw.strWN);
			if (m_nWellIndex == DEGUBINDEX)
				WriteLog(strTemp);
			::EnterCriticalSection(&m_cOther);
			gl.m_strErrorMsg = _T("Error：PostWellRT->soap_end_recv: ") + strWN;
			::LeaveCriticalSection(&m_cOther);
			throw std::runtime_error("SOAP end receive failed");
		}

		strReturn.Format(_T("%s"), char2wchar(buf));
		::EnterCriticalSection(&m_cOther);
		gl.m_nNewDataTime = CTime::GetCurrentTime().GetTime();
		::LeaveCriticalSection(&m_cOther);
	}
	catch (const std::exception& ex)
	{
		std::string tt = "Exception in PostWellRT:";
		tt += ex.what();
		WriteLog(tt);
		strReturn = _T("");  // 返回空字符串表示错误
	}
	catch (...)
	{
		// 捕获其他异常
		WriteLog(_T("Unknown exception in PostWellRT"));
		strReturn = _T("");  // 返回空字符串表示错误
	}

	// 资源回收
	if (soap)
	{
		soap_destroy(soap);
		soap_end(soap);
		soap_done(soap);
		soap_free(soap);
	}

	if (urlpost)
		delete[] urlpost;
	if (context)
		delete[] context;

	return strReturn;
}

//数据处理线程
UINT CTlmWebserviceThread::ThreadFunc(int nIndex)
{
	CString strTemp;
	try
	{
		strTemp.Format(_T("ThreadFunc实时数据查询 %d，%s，ID：%s ================================================"), nIndex, sw.strWN, sw.strWBID);
		//if (nIndex == DEGUBINDEX)
			WriteLog(strTemp);

		CString data = sw.GenPostContent();
		CString strJson = PostWellRT(gl.m_strBearerCode, gl.m_strClientID, data, sw.strWN);
		strTemp.Format(_T("ThreadFunc实时数据查询结果strJson：\t%s"), strJson);
		if (nIndex == DEGUBINDEX)
			WriteLog(strTemp);

		if (strJson.IsEmpty() || strJson == _T("[]") || strJson.Find(_T("error")) > 0)
		{
			sw.nNewDataTime = sw.nNewDataTime + gl.m_nTimeSpan + 2;
			//if (nIndex == DEGUBINDEX)
			strTemp.Format(_T("PostWellRT 查询失败：token:%s, id:%s, wn:%s"), gl.m_strBearerCode, gl.m_strClientID, sw.strWN);
			WriteLog(strTemp);
			return 0;
		}

		sw.ParseParValJson(strJson);

		if (sw.nLastDataTime != sw.nNewDataTime)
		{
			strTemp.Format(_T("实时数据查询结果 更新 %ld---%ld"), sw.nLastDataTime, sw.nNewDataTime);
			if (nIndex == DEGUBINDEX)
				WriteLog(strTemp);
			sw.nLastDataTime = sw.nNewDataTime;
			if (sw.nToYqh == 1 && gl.m_nToYqh == 1)
			{
				sw.YqhDbOprator();
			}
			if (sw.nToYqhUrl == 1 && gl.m_nToYqhUrl == 1)
			{
				sw.YqhOpratorUrl();
			}
			if (sw.nToZxq == 1 && gl.m_nToMaster == 1)
			{
				sw.ZxqDbOprator();
			}

			if (sw.nToKD == 1 && gl.m_nToKd == 1)
			{
				sw.KDDbOprator();
			}
			//strTemp.Format(_T("准备Redis数据写入 %d---%s"), nIndex, sw.strWN);
			//if (nIndex == DEGUBINDEX)
			//	WriteLog(strTemp);

			if (gl.m_bConnectRedis)
			{
				strTemp = sw.GenSetRedisString();
				REDIS_REC rr;
				rr.strFieldName = _T("REALTIME_DATA:") + sw.strWN;
				rr.strValue = strTemp;
				::EnterCriticalSection(&m_cRedis);
				m_aRR.Add(rr);
				::LeaveCriticalSection(&m_cRedis);
				sw.nRedisDataTime = CTime::GetCurrentTime().GetTime();
			}
		}
		else
		{
			//strTemp.Format(_T("实时sw.nLastDataTime == sw.nNewDataTime"));
			//if (nIndex == DEGUBINDEX)
			//	WriteLog(strTemp);
		}
	}
	catch (...)
	{
		strTemp.Format(_T("ThreadFunc 发生异常 %d---%s"), nIndex, sw.strWN);
		//if (nIndex == DEGUBINDEX)
			WriteLog(strTemp);
	}
	::EnterCriticalSection(&m_cWS);
	gl.tlm.m_aWells.SetAt(nIndex, sw);
	::LeaveCriticalSection(&m_cWS);

	//strTemp.Format(_T("实时数据查询结束 %d---%s"), nIndex, sw.strWN);
	//if (nIndex == DEGUBINDEX)
	//	WriteLog(strTemp);

	return 0;
}

BOOL CTlmWebserviceThread::InitInstance()
{
	// TODO:    在此执行任意逐线程初始化
	CString strTemp;

	strTemp = _T("InitInstance 开始");
	WriteLog(strTemp);

	Sleep(1000);
	strTemp.Format(_T("实时数据查询Thread %d---%s"), m_nWellIndex, sw.strWN);
	//WriteLog(strTemp);
	while (1)
	{
		sw = gl.tlm.m_aWells.GetAt(m_nWellIndex);
		sw.m_stop = false;
		if (g_bExitApp)
		{
			strTemp = _T("InitInstance 检测到应用程序退出");
			WriteLog(strTemp);
			break;
		}

		if (sw.bErrorGetPars)
		{
			strTemp = _T("InitInstance 检测到参数获取错误");
			WriteLog(strTemp);
			break;
		}

		DWORD tTickCount = GetTickCount();
		if (sw.nToKD == 1 || sw.nToZxq == 1 || sw.nToYqh == 1 || sw.nToYqhUrl == 1)
		{
			ThreadFunc(m_nWellIndex);
		}
		DWORD tNowTickCount = GetTickCount();
		DWORD tSpan = tNowTickCount - tTickCount;
		int nSleep = gl.m_nTimeSpan * 1000;
		if (nSleep > tSpan)
		{			
			nSleep -= tSpan;
			Sleep(nSleep);
		}
		else
		{
			Sleep(2000);
		}
	}

	strTemp.Format(_T("实时数据查询Thread结束 %d---%s"), m_nWellIndex, sw.strWN);
	std::cout << strTemp.GetString() << std::endl;
	WriteLog(strTemp);
	return TRUE;
}

int CTlmWebserviceThread::ExitInstance()
{
	// TODO:    在此执行任意逐线程清理
	return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CTlmWebserviceThread, CWinThread)
END_MESSAGE_MAP()


// CTlmWebserviceThread 消息处理程序
